﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using DevelopStudio.Common.Basic;
using System.Windows.Forms;
using SNSHelper.Common;
using System.Diagnostics;
using SharpSvn;


namespace DevelopStudio.Common.Manage
{
    public static class Utility
    {
        static Utility()
        {
            if (Directory.Exists(TempStudioPath) == false)
            {
                Directory.CreateDirectory(TempStudioPath);
            }

            if (Directory.Exists(TempDiffPath) == false)
            {
                Directory.CreateDirectory(TempDiffPath);
            }
        }

        public static readonly string TempStudioPath = Path.GetFullPath(Path.GetTempPath() + "DevelopStudio");

        public static readonly string TempDiffPath = Path.GetFullPath(Path.GetTempPath() + "DevelopDiff");

        #region Xml Serialized

        public static void SerializedObject2File(object value, string fileFullPath)
        {
            if (File.Exists(fileFullPath) == true)
            {
                File.Delete(fileFullPath);
            }

            XmlSerializer serializer = new XmlSerializer(value.GetType());

            using (TextWriter writer = new StreamWriter(fileFullPath))
            {
                serializer.Serialize(writer, value);
            }
        }

        public static T SerializedFile2Object<T>(string fileFullPath)
        {
            if (File.Exists(fileFullPath) == false)
            {
                return default(T);
            }

            XmlSerializer serializer = new XmlSerializer(typeof(T));

            using (FileStream fs = new FileStream(fileFullPath, FileMode.Open))
            {
                return (T)serializer.Deserialize(fs);
            }
        }

        public static string SerializedObject2Xml(object value)
        {
            XmlSerializer serializer = new XmlSerializer(value.GetType());

            using (MemoryStream stream = new MemoryStream())
            {
                serializer.Serialize(stream, value);
                byte[] buff = stream.GetBuffer();
                return Encoding.Default.GetString(buff, 0, buff.Length);
            }
        }

        public static T SerializedXml2Object<T>(string xml)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));

            using (MemoryStream stream = new MemoryStream(Encoding.Default.GetBytes(xml)))
            {
                return (T)serializer.Deserialize(stream);
            }
        }

        #endregion

        #region ShowMessage

        public static void ShowMessage(Label label, string message, MessageLevel level)
        {
            switch (level)
            {
                case MessageLevel.Critical:
                    {
                        label.ForeColor = System.Drawing.Color.Red;
                    }
                    break;

                case MessageLevel.Warning:
                    {
                        label.ForeColor = System.Drawing.Color.Yellow;
                    }
                    break;
                default:
                    {
                        label.ForeColor = System.Drawing.Color.Blue;
                    }
                    break;
            }

            label.Text = message;
        }

        #endregion 

        public static string StatusDisplayName(Basic.SvnStatus action)
        {
            switch (action)
            {
                case Basic.SvnStatus.Added:
                    return Properties.Resources.StatusAdded;
                case Basic.SvnStatus.Deleted:
                    return Properties.Resources.StatusDeleted;
                case Basic.SvnStatus.Modified:
                    return Properties.Resources.StatusModified;
                default:
                    return action.ToString();
            }
        }

        /*
        public static string GetExtension(string path)
        {
            if (string.IsNullOrEmpty(path) == true)
            {
                return string.Empty;
            }

            int index = path.LastIndexOf('.');

            if (index == -1)
            {
                return string.Empty;
            }

            return path.Substring(index);
        }
         * */

        #region CMD Shell

        public static void ExecuteCmd(string exec, string param)
        {
            System.Diagnostics.Process.Start(exec, param);
        }

        public static string ExecuteCmd(string cmd)
        {
            using (Process p = new Process())
            {
                p.StartInfo.FileName = "cmd.exe";

                //关闭Shell的使用
                p.StartInfo.UseShellExecute = false;

                //重新定向标准输入，输入，错误输出
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;

                //设置cmd窗口不显示
                p.StartInfo.CreateNoWindow = true;

                p.Start();
                p.StandardInput.WriteLine(cmd);
                p.StandardInput.WriteLine("exit");
                return p.StandardOutput.ReadToEnd();
            }
        }

        #endregion


        private static string PathSafeRevision(long revision)
        {
            if (revision == AppConst.LocalRevision)
            {
                return AppConst.WorkingCopy;
            }
            else if (revision == AppConst.LocalRevision)
            {
                return AppConst.NewAdded;
            }

            return revision.ToString();
        }

        public static string GetName(string filename, long rev, int reNum = 0)
        {
            if (string.IsNullOrEmpty(filename))
                throw new ArgumentNullException("filename");

            if (reNum == 0)
            {
                return (Path.GetFileNameWithoutExtension(filename) + "." + PathSafeRevision(rev) + Path.GetExtension(filename));
            }
            else
            {
                return (Path.GetFileNameWithoutExtension(filename) + reNum.ToString() + "." + PathSafeRevision(rev) + Path.GetExtension(filename));
            }
        }

        private static string GetTempFullFileName(string filename, long rev, string basePath)
        {
            string file;
            int num = 0;
            filename = filename.Replace("/", "_");
            filename = filename.Replace("\\", "_");
            string name = GetName(filename, rev, num);

            while (true)
            {
                file = Path.Combine(basePath, name);

                try
                {
                    if (File.Exists(file) == true)
                    {
                        File.Delete(file);
                    }

                    return file;
                }
                catch (Exception)
                {
                    num++;
                    name = GetName(filename, rev, num);
                }
            }
        }

        public static string GetStudioTempFullFileName(string filename, long rev)
        {
            return GetTempFullFileName(filename, rev, TempStudioPath);
        }

        public static string GetDiffTempFullFileName(string filename, long rev)
        {
            return GetTempFullFileName(filename, rev, TempDiffPath);
        }
    }
}
